﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FileSystem.Models;
using FileSystem.Services.IServices;
using SQLite;

namespace FileSystem.Services.Realization {
    /// <summary>
    /// 用户存储
    /// </summary>
    public class UserStorage : IUserStorage {
        // ******** 公开变量
        /// <summary>
        /// UserTable文件路径
        /// </summary>
        public static readonly string DbPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder
                .LocalApplicationData), DbName);

        /// <summary>
        /// UserTable数据库连接
        /// </summary>
        private SQLiteAsyncConnection _connection;

        public SQLiteAsyncConnection Connection =>
            _connection ?? (_connection = new SQLiteAsyncConnection(DbPath));

        // ******** 私有变量
        /// <summary>
        /// TableDb文件名
        /// </summary>
        private const string DbName = "UserTable.sqlite3";

        /// <summary>
        /// 偏好存储服务
        /// </summary>
        private IPreferenceStorage _preferenceStorage;


        // ******** 继承方法

        /// <summary>
        /// 初始化用户存储
        /// </summary>
        public async Task InitializeAsync() {
            // UserTable.sqlite3 文件初始化
            await Connection.CreateTableAsync<User>();

            //将程序自带的用户写入表中,不用AddAsync,减少耦合度
            foreach (var user in UserConst.Users)
                await Connection.InsertAsync(user);

            _preferenceStorage.Set(UserStorageConstants.VersionKey,
                UserStorageConstants.Version);
        }

        /// <summary>
        /// 用户存储是否已经初始化
        /// </summary>
        public bool IsInitialized() {
            return _preferenceStorage.Get(UserStorageConstants.VersionKey,
                    UserStorageConstants.DefaultVersion) ==
                UserStorageConstants.Version;
        }

        /// <summary>
        /// 增加用户
        /// </summary>
        /// <param name="user">要添加的用户</param>
        public async Task AddAsync(User user) {
            await Connection.InsertAsync(user);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="user">要删除的用户</param>
        public async Task RemoveAsync(User user) {
            await Connection.DeleteAsync(user);
        }

        /// <summary>
        /// 修改用户属性
        /// </summary>
        /// <param name="user">用户</param>
        /// <param name="property">属性</param>
        /// <param name="newContent">新值</param>
        public async Task ModifyProperty(User user, UserConst.Property property,
            string newContent) {
            switch (property) {
                case UserConst.Property.UserName: {
                    await ModifyAsync(user, UserConst.Property.UserName, newContent);
                        break;
                }
                case UserConst.Property.Password: {
                    await ModifyAsync(user, UserConst.Property.Password, newContent);
                    break;
                }
                case UserConst.Property.Image: {
                    await ModifyAsync(user, UserConst.Property.Image, newContent);
                    break;
                }
                case UserConst.Property.Description: {
                    await ModifyAsync(user, UserConst.Property.Description, newContent);
                    break;
                }
            }
        }

        /// <summary>
        /// 修改用户属性
        /// </summary>
        /// <param name="user">用户</param>
        /// <param name="property">属性</param>
        /// <param name="newContent">新值</param>
        public async Task ModifyProperty(User user, UserConst.Property property,
            int newContent) {
            switch (property) {
                case UserConst.Property.Authority: {
                    await ModifyAsync(user, UserConst.Property.Authority, newContent);
                    break;
                }
            }
        }

        /// <summary>
        /// 根据用户名获得一个用户
        /// </summary>
        /// <param name="userName">用户名</param>
        public async Task<User> GetUser(string userName) {
            return await Connection.Table<User>()
                .FirstOrDefaultAsync(p => p.UserName == userName);
        }

        /// <summary>
        /// 获得所有用户
        /// </summary>
        public async Task<IList<User>> GetUsers() {
            return await Connection.Table<User>().ToListAsync();
        }

        /// <summary>
        /// 判断用户是否存在
        /// </summary>
        /// <param name="userName">用户名</param>
        public async Task<bool> Exist(string userName) {
            var item = await Connection.Table<User>()
                .FirstOrDefaultAsync(p => p.UserName == userName);
            if (item == null)
                return false;
            else
                return true;
        }

        // ******** 公开方法
        /// <summary>
        /// 用户存储
        /// </summary>
        public UserStorage(IPreferenceStorage preferenceStorage) {
            _preferenceStorage = preferenceStorage;
        }

        /// <summary>
        /// 关闭数据库
        /// </summary>
        public async Task CloseAsync() {
            await Connection.CloseAsync();
        }

        // ******** 私有方法

        private async Task ModifyAsync(User user, UserConst.Property property,
            string newContent) {
            var list = await Connection.Table<User>().ToListAsync();
            var index = -1;
            for (var i = 0; i < list.Count; i++)
                if (user.UserName == list[i].UserName) {
                    index = i;
                    break;
                }

            foreach (var userInlist in list)
                await Connection.DeleteAsync(userInlist);
            switch (property) {
                case UserConst.Property.UserName: {
                    user.UserName = newContent;
                    break;
                }
                case UserConst.Property.Password: {
                    user.Password = newContent;
                    break;
                }
                case UserConst.Property.Image: {
                    user.Image = newContent;
                    break;
                }
                case UserConst.Property.Description: {
                    user.Description = newContent;
                    break;
                }
            }

            list[index] = user;
            foreach (var userInlist in list)
                await Connection.InsertAsync(userInlist);
        }

        private async Task ModifyAsync(User user, UserConst.Property property,
            int newContent) {
            var list = await Connection.Table<User>().ToListAsync();
            var index = -1;
            for (var i = 0; i < list.Count; i++)
                if (user.UserName == list[i].UserName) {
                    index = i;
                    break;
                }

            foreach (var userInlist in list)
                await Connection.DeleteAsync(userInlist);
            switch (property) {
                case UserConst.Property.Authority: {
                    user.Authority = newContent;
                    break;
                }
            }

            list[index] = user;
            foreach (var userInlist in list)
                await Connection.InsertAsync(userInlist);
        }
    }
}